<?php
declare(strict_types=1);

namespace app\service;


/**
 * 微信服务门面类
 * 整合小程序和加密解密功能
 */
class WechatService
{
    /**
     * 小程序服务实例
     * @var MiniProgramService
     */
    protected $miniProgram;
    
    /**
     * 加密服务实例
     * @var EncryptionService
     */
    protected $encryption;
    
    /**
     * 构造函数
     * @param MiniProgramService|null $miniProgram 小程序服务实例
     * @param EncryptionService|null $encryption 加密服务实例
     */
    public function __construct(MiniProgramService $miniProgram = null, EncryptionService $encryption = null)
    {
        $this->miniProgram = $miniProgram ?? new MiniProgramService();
        $this->encryption = $encryption ?? new EncryptionService();
    }

    /**
     * 获取小程序服务实例
     * @return MiniProgramService
     */
    public function getMiniProgram(): MiniProgramService
    {
        return $this->miniProgram;
    }
    
    /**
     * 获取加密服务实例
     * @return EncryptionService
     */
    public function getEncryption(): EncryptionService
    {
        return $this->encryption;
    }
    
    /**
     * 获取小程序openid
     * @param string $code 登录时获取的code
     * @return string openid
     */
    public function getOpenid(string $code): string
    {
        return $this->miniProgram->getOpenid($code);
    }
    
    /**
     * 获取会话信息
     * @param string $code 登录时获取的code
     * @return array 包含session_key、openid等信息的数组
     */
    public function getSessionInfo(string $code): array
    {
        return $this->miniProgram->getSessionInfo($code);
    }
    
    /**
     * 解密小程序加密数据
     * @param string $sessionKey 会话密钥
     * @param string $encryptedData 包括敏感数据在内的完整用户信息的加密数据
     * @param string $iv 加密算法的初始向量
     * @return array 解密后的数据
     */
    public function decryptData(string $sessionKey, string $encryptedData, string $iv): array
    {
        return $this->miniProgram->decryptData($sessionKey, $encryptedData, $iv);
    }
    
    /**
     * 处理小程序登录数据
     * @param array $data 包含加密数据的数组
     * @return array 处理结果
     */
    public function handleLoginData(array $data): array
    {
        return $this->miniProgram->handleLoginData($data);
    }
    
    /**
     * 解密请求数据
     * @param array $requestData 请求数据
     * @return array 解密后的数据
     */
    public function decryptRequest(array $requestData): array
    {
        return $this->encryption->decryptRequest($requestData);
    }
    
    /**
     * 加密响应数据
     * @param array|string $data 待加密数据
     * @param string $nonce 随机数
     * @return array 加密后的响应数据
     */
    public function encryptResponse($data, string $nonce): array
    {
        return $this->encryption->encryptResponse($data, $nonce);
    }
    
    /**
     * 验证签名
     * @param array $requestData 请求数据
     * @return bool 签名是否有效
     */
    public function verifySign(array $requestData): bool
    {
        return $this->encryption->verifySign($requestData);
    }
    
    /**
     * AES-256-CBC加密
     * @param string $data 待加密数据
     * @param string $nonce 随机数，用于生成初始向量
     * @param bool $base64Encode 是否进行base64编码，默认true
     * @return string 加密后的数据
     */
    public function encrypt(string $data, string $nonce, bool $base64Encode = true): string
    {
        return $this->encryption->encrypt($data, $nonce, $base64Encode);
    }
    
    /**
     * AES-256-CBC解密
     * @param string $encryptedData 加密数据
     * @param string $nonce 随机数，用于生成初始向量
     * @param bool $base64Decode 是否需要先进行base64解码，默认true
     * @return string 解密后的数据
     */
    public function decrypt(string $encryptedData, string $nonce, bool $base64Decode = true): string
    {
        return $this->encryption->decrypt($encryptedData, $nonce, $base64Decode);
    }

}